﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ToDoTasks.DataLayer;
using ToDoTasks.Classes;
using ToDoTasks.Services.Models;

namespace ToDoTasks.Services.Controllers
{
    public class TaskController : ApiController
    {
        [HttpPost]
        [ActionName("create")]
        public HttpResponseMessage Create([FromBody]TaskData data, string sessionKey)
        {
            ToDoTasksEntities sqlcon = new ToDoTasksEntities();

            var user = GetUserBySessinKey(sessionKey, sqlcon);
            if (user == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "User is not found");
            }

            if (data.Content == null || data.EventDate == DateTime.MinValue ||
                data.LastUpdate == DateTime.MinValue ||
                data.Title == null || data.Remainder == DateTime.MinValue)
            {
                return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Data is incorrect");
            }

            Task newTask = new Task()
            {
                Content = data.Content,
                EventDate = data.EventDate,
                Prioriry = 0,
                Status = Varibles.TaskStarted,
                Title = data.Title,
                UserId = user.Id,
                LastUpdate = data.LastUpdate,
                Remainder = data.Remainder
            };

            sqlcon.Tasks.Add(newTask);
            sqlcon.SaveChanges();

            TaskData task = new TaskData()
            {
                Content = newTask.Content,
                EventDate = newTask.EventDate,
                Id = newTask.Id,
                LastUpdate = newTask.LastUpdate,
                Priority = newTask.Prioriry,
                Remainder = newTask.Remainder,
                Status = newTask.Status,
                Title = newTask.Title
            };

            return this.Request.CreateResponse(HttpStatusCode.Created, task);
        }

        [HttpPut]
        [ActionName("update")]
        public HttpResponseMessage Update([FromBody]TaskData data, int id, string sessionKey)
        {
            ToDoTasksEntities sqlcon = new ToDoTasksEntities();

            var user = GetUserBySessinKey(sessionKey, sqlcon);
            if (user == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "User is not found");
            }

            Task task = GetTaskById(id, user.Id, sqlcon);

            if (task == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "Task not found");
            }

            if (data.Content == null || data.EventDate == DateTime.MinValue ||
                data.LastUpdate == DateTime.MinValue || data.Priority == 0 ||
                data.Title == null || data.Remainder == DateTime.MinValue)
            {
                return this.Request.CreateResponse(HttpStatusCode.BadRequest, "Data is incorrect");
            }

            task.Content = data.Content;
            task.EventDate = data.EventDate;
            task.Title = data.Title;
            task.Prioriry = data.Priority;
            task.Remainder = data.Remainder;
            task.Title = data.Title;
            task.LastUpdate = data.LastUpdate;

            sqlcon.SaveChanges();

            return this.Request.CreateResponse(HttpStatusCode.OK);
        }

        [HttpDelete]
        [ActionName("delete")]
        public HttpResponseMessage Delete(int id, string sessionKey)
        {
            ToDoTasksEntities sqlcon = new ToDoTasksEntities();

            var user = GetUserBySessinKey(sessionKey, sqlcon);
            if (user == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "User is not found");
            }

            Task task = GetTaskById(id, user.Id, sqlcon);

            if (task == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "Task not found");
            }

            sqlcon.Tasks.Remove(task);
            sqlcon.SaveChanges();

            return this.Request.CreateResponse(HttpStatusCode.Accepted);
        }

        [HttpGet]
        [ActionName("finish")]
        public HttpResponseMessage Get(int id, string sessionKey)
        {
            ToDoTasksEntities sqlcon = new ToDoTasksEntities();

            var user = GetUserBySessinKey(sessionKey, sqlcon);
            if (user == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "User is not found");
            }

            Task task = GetTaskById(id, user.Id, sqlcon);

            if (task == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "Task not found");
            }

            task.Status = Varibles.TaskFinished;
            sqlcon.SaveChanges();

            return this.Request.CreateResponse(HttpStatusCode.OK);
        }

        private User GetUserBySessinKey(string sessionKey, ToDoTasksEntities sqlcon)
        {
            var result =
                (from user in sqlcon.Users
                 where user.SessionKey == sessionKey
                 select user).FirstOrDefault();

            return result;
        }

        private Task GetTaskById(int id, int userId, ToDoTasksEntities sqlcon)
        {
            var result =
                (from task in sqlcon.Tasks
                 where task.Id == id
                 && task.Status == Varibles.TaskStarted
                 && task.UserId == userId
                 select task).FirstOrDefault();

            return result;
        }

        private IQueryable<Task> GetAllTaskByUser(int userId, ToDoTasksEntities sqlcon)
        {
            var result =
                (from task in sqlcon.Tasks
                 where task.UserId == userId
                 select task);

            return result;
        }
    }
}
